package com.prueba.client.extensiones;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;

import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.DataSourceField;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridRecord;

public abstract class MyDataSource<Dato> extends DataSource{
	
	//Tendrian que ir en la interfaz Dato
	protected abstract ListGridRecord toListGridRecord(Dato d);
	protected abstract Dato toDato(Record r);
	
	protected abstract boolean actualizarCampo(Par<Dato,ListGridRecord> dato,String campo,Object valor);
	public abstract String obtenerClave(Dato dato);
	//-----------------------------------
	protected abstract DataSourceField[] getDataSourceFields();
	
	protected ListGrid construirListGrid(){
		ListGrid grilla=new ListGrid();
		grilla.setWidth100();  
		grilla.setHeight100(); 
		grilla.setOverflow(Overflow.AUTO);
		grilla.setAutoFetchData(false);
		return grilla;
	}
	
	//-----------------------------------
	/**
	 * TODO VOLVER A PROTECTED DATOS
	 */
	public Map<String,Par<Dato,ListGridRecord>> datos;
	protected ListGrid dataBound;
	
	protected MyDataSource(String id){
		this.setID(id);
        setFields(getDataSourceFields());  
        setClientOnly(true);
        
		this.datos=new HashMap<String,Par<Dato,ListGridRecord>>();
		setListGrid(construirListGrid());
	}

	public ListGrid getListGrid(){
		return dataBound;
	}
	public void setListGrid(ListGrid dataBound){
		this.dataBound=dataBound;
		dataBound.setDataSource(this);
		//dataBound.setAutoFetchData(false);
	}
	
	public void vaciar(){
		this.datos.clear();
		this.dataBound.selectAllRecords();
		this.dataBound.removeSelectedData();
	}
	
	public void cargarDatos(Collection<Dato> nuevosdatos){
		vaciar();
		
		for(Iterator<Dato> it=nuevosdatos.iterator();it.hasNext();){
			Dato d=it.next();
			ListGridRecord r=this.toListGridRecord(d);
			this.datos.put(obtenerClave(d), new Par<Dato,ListGridRecord>(d,r));
			this.addData(r);
		}
		this.dataBound.fetchData();
	}
	public boolean agregarElemento(Dato d){
		if(this.datos.containsKey(obtenerClave(d)))
			return false;
		else{
			ListGridRecord r=this.toListGridRecord(d);
			this.datos.put(obtenerClave(d), new Par<Dato,ListGridRecord>(d,r));
			this.addData(r);
			//this.dataBound.addData(r);
			return true;
		}
	}
	public boolean removerElemento(String clave){
		Par<Dato,ListGridRecord> dato=this.datos.get(clave);
		if(dato!=null){
			this.datos.remove(clave);
			this.removeData(dato.segundo);
			
			//this.dataBound.removeData(dato.segundo);
			return true;
		}else
			return false;
	}
	public boolean actualizarElemento(String clave,String campo,Object valor){
		Par<Dato,ListGridRecord> dato=this.datos.get(clave);
		if(dato!=null){
			if(actualizarCampo(dato, campo, valor)){
				this.updateData(dato.segundo);
				//this.dataBound.updateData(dato.segundo);
				return true;
			}else
				return false;
		}else
			return false;
	}

	public Dato getElemento(String clave){
		Par<Dato,ListGridRecord> dato=this.datos.get(clave);
		if(dato!=null)
			return dato.primero;
		else
			return null;
	}
	
	public Collection<Dato> getElementos(){
		LinkedList<Dato> elementos=new LinkedList<Dato>();
		
		Iterator<Entry<String, Par<Dato, ListGridRecord>>> it=this.datos.entrySet().iterator();
		while(it.hasNext()){
			elementos.add(it.next().getValue().primero);
		}
		return elementos;
	}
}
